Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement auto-recover functionality [B: 1403] #483

Open
wants to merge 34 commits into
base: dev
Choose a base branch
from

Conversation

droberts-ctrlo
Copy link
Contributor

No description provided.

@droberts-ctrlo droberts-ctrlo changed the title Reset and rerun of commit Reset and rerun of commit [B: 1403] Dec 2, 2024
@droberts-ctrlo droberts-ctrlo marked this pull request as draft December 2, 2024 14:53
@droberts-ctrlo droberts-ctrlo marked this pull request as ready for review December 16, 2024 10:36
@abeverley abeverley changed the title Reset and rerun of commit [B: 1403] Implement auto-recover functionality [B: 1403] Dec 19, 2024
Copy link
Contributor

@abeverley abeverley left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great work Dave, this is looking really good. I've made a few minor comments so far. I'd also like to test it in practice, but I'm getting Uncaught (in promise) TypeError: crypto.subtle is undefined - any ideas?

lib/GADS.pm Outdated Show resolved Hide resolved
lib/GADS.pm Outdated Show resolved Hide resolved
src/frontend/components/modal/modals/curval/index.js Outdated Show resolved Hide resolved
Also moved ID for current record out of Curval condition
- Added checks to ensure encryption is available for Autorecover
- Improved encrypted storage testing
- Added NullStorage to disable storage without having to search through all code
- Added tests for NullStorage, AppStorage, and GADSStorage classes
- Updated test definitions to allow for crypto testing

As noted above the modal and field components will not have recovery enabled should encryption be unavailable within storage; this is in order to meet standards for ISO:27001 (DARE is mandatory) - the `setValue` function in the `curval` component should never be called when this is the case, but in case it is, the Null Receiver pattern is used (hence the `NullStorage`, which is a full no-op storage solution for our use case).
@@ -178,7 +178,7 @@ jobs:

strategy:
matrix:
node-version: [18.x, 20.x]
node-version: [18.x, 20.x, 22.x]
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Update to use all currently supported node versions

@@ -187,6 +187,7 @@ jobs:
uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node-version }}
cache: 'yarn'
cache: 'npm'
- run: npx update-browserslist-db@latest
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cache and browsers list for 18.x was "complaining"

@@ -94,6 +94,9 @@ const config = {
"^validation$": "<rootDir>/src/frontend/js/lib/validation",
"^logging$": "<rootDir>/src/frontend/js/lib/logging",
"^util/(.*)$": "<rootDir>/src/frontend/js/lib/util/$1",
"^components/(.*)$": "<rootDir>/src/frontend/components/$1",
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Mapping was inconsistent between this file and tsconfig.json

@@ -1448,6 +1448,17 @@ any ['get', 'post'] => '/api/users' => require_any_role [qw/useradmin superadmin
return encode_json $return;
};

get '/api/get_key' => require_login sub {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Moved to API route for consistency

$el.on('click', async () => {
const href = $el.data('href');
await clearSavedFormValues($el.closest('form'));
if (href)
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should only work for buttons, and should have the HREF value set (to make the button act like a link where used) - if it isn't, just go back in the history.

@@ -83,7 +84,7 @@ class DocumentComponent {

async handleAjaxUpload(uri: string, csrf_token: string, file: File) {
try {
if (!file) throw this.showException(new Error('No file provided'));
if (!file) this.showException(new Error('No file provided'));
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Incorrect statement usage

@@ -181,5 +184,7 @@ class DocumentComponent {
* @param {JQuery<HTMLElement> | HTMLElement} el The element to attach the document component to
*/
export default function documentComponent(el: JQuery<HTMLElement> | HTMLElement) {
Promise.all([(new DocumentComponent(el)).init()]);
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We actually need a component to be returned here now

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All that's changed here is the change to check for jQuery being defined so all the tests pass as expected

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Abstract factory to create the relevant storage provider

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These tests are skipped on Node 18

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not entirely sure what the difference here is, but it works like this (as opposed to the previous version) so I'm not worried.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These tests are related to the common utility library and had to be changed due to the changes to said library.

See the comment on the library for reasoning for this change being included here

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This involved importing the globals.definitions into the packaged code—this is bad practice and meant that some functions were being replaced by stubs and/or mocks.

Whilst this has not had any effect at this point, it will become a source of bugs and/or errors going forward, and required removal.

Said behaviour was only placed in for previous requirement that has since been removed

// For each field, when it changes save the value to the local storage
$field.on('change', async function () {
const recovering = await self.storage.getItem('recovering');
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Easiest way to ensure we're not writing data when we don't need to during a recovery

}

async setItem(key: string, value: string) {
if(await this.getItem('recovering')) return;
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We turn off writing if we're performing a recovery to prevent extra write operations—this is more to prevent the odd curval error with dropdowns.

It's felt it's more sensible to do this here, rather than search through all the code and try to work out where to put the check (and repeat it ad infinitum)

It was found that due to the curval recovery working on events, it was sometimes triggering a write when one isn't required.
Test condition was returning true in unit tests meaning tests failed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants